//
//  ZYThreadBacktrace.m
//  ZYWebImage
//
//  Created by wangzhipan on 2025/5/7.
//

#import "ZYThreadBacktrace.h"
#import <dlfcn.h>
#import <pthread.h>
#import <sys/types.h>
#import <limits.h>
#import <string.h>
#import <mach-o/dyld.h>
#import <mach-o/nlist.h>

// 最大堆栈深度
#define kMaxBacktraceDepth 128

// 线程状态定义
#if defined(__arm64__)
    #define ZY_THREAD_STATE_COUNT ARM_THREAD_STATE64_COUNT
    #define ZY_THREAD_STATE ARM_THREAD_STATE64
    #define ZY_FRAME_POINTER __fp
    #define ZY_STACK_POINTER __sp
    #define ZY_INSTRUCTION_ADDRESS __pc
#elif defined(__arm__)
    #define ZY_THREAD_STATE_COUNT ARM_THREAD_STATE_COUNT
    #define ZY_THREAD_STATE ARM_THREAD_STATE
    #define ZY_FRAME_POINTER __r[7]
    #define ZY_STACK_POINTER __sp
    #define ZY_INSTRUCTION_ADDRESS __pc
#elif defined(__x86_64__)
    #define ZY_THREAD_STATE_COUNT x86_THREAD_STATE64_COUNT
    #define ZY_THREAD_STATE x86_THREAD_STATE64
    #define ZY_FRAME_POINTER __rbp
    #define ZY_STACK_POINTER __rsp
    #define ZY_INSTRUCTION_ADDRESS __rip
#elif defined(__i386__)
    #define ZY_THREAD_STATE_COUNT x86_THREAD_STATE32_COUNT
    #define ZY_THREAD_STATE x86_THREAD_STATE32
    #define ZY_FRAME_POINTER __ebp
    #define ZY_STACK_POINTER __esp
    #define ZY_INSTRUCTION_ADDRESS __eip
#endif

@implementation ZYThreadBacktrace
#pragma mark - 线程挂起与恢复
/**
 * 挂起除当前线程外的所有线程
 * @return 挂起的线程数组
 */
+ (NSArray<NSNumber *> *)suspendAllThreadsExceptCaller
{
    // 获取当前线程
    mach_port_t currentThread = mach_thread_self();
    NSMutableArray <NSNumber *>*suspendThreads = [NSMutableArray array];
    
    // 获取所有线程
    thread_act_array_t threads;
    mach_msg_type_number_t threadCount = 0;
    kern_return_t kr = task_threads(mach_task_self(), &threads, &threadCount);
    
    if (kr != KERN_SUCCESS) {
        // 释放当前线程引用
        mach_port_deallocate(mach_task_self(), currentThread);
        return suspendThreads;
    }
    
    // 遍历并挂起所有非当前线程
    for (mach_msg_type_number_t i = 0; i < threadCount; i++) {
        thread_t thread = threads[i];
        if (thread != currentThread) {
            // 挂起线程
            kern_return_t kr = thread_suspend(thread);
            if (kr == KERN_SUCCESS) {
                [suspendThreads addObject:@(thread)];
            }
        }
        // 释放线程引用（避免内存泄漏）
        mach_port_deallocate(mach_task_self(), thread);
    }
    // 释放线程列表
    vm_deallocate(mach_task_self(), (vm_address_t)threads, sizeof(thread_t) * threadCount);
    // 释放当前线程引用
    mach_port_deallocate(mach_task_self(), currentThread);
    return suspendThreads;
}

/**
 * 恢复之前挂起的线程
 * @param threads 之前挂起的线程数组
 */
+ (void)resumeThreads:(NSArray<NSNumber *> *)threads
{
    for (NSNumber *threadNum in threads) {
        thread_t thread = [threadNum unsignedIntValue];
        // 恢复线程执行
        kern_return_t kr = thread_resume(thread);
        if (kr != KERN_SUCCESS) {
            NSLog(@"Failed to resume thread %u: %s", thread, mach_error_string(kr));
        }
    }
}

#pragma mark - 堆栈捕获
/**
 * 获取所有线程的堆栈信息
 * @param isSkipCurrent 是否跳过当前线程
 * @return 包含所有线程堆栈的字典
 */
+ (NSDictionary *)captureAllThreadsBacktrace:(BOOL)isSkipCurrent
{
    //获取当前线程
    mach_port_t currentThread = mach_thread_self();
    
    NSMutableDictionary *bacetrace = [NSMutableDictionary dictionary];
    
    //获取所有线程
    mach_msg_type_number_t threadCount = 0;
    thread_act_array_t threads;
    kern_return_t kr = task_threads(mach_task_self(), &threads, &threadCount);
    if (kr != KERN_SUCCESS) {
        
    }
}
@end
